package org.cjstudio.holypoopsgrs.resource;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.cjstudio.holypoopsgrs.model.UserProfile;
import org.cjstudio.holypoopsgrs.model.UserRecord;
//import org.cjstudio.holypoopsgrs.security.절대뚫리지않는굉장히복잡한알고리즘;
import org.cjstudio.holypoopsgrs.server.Repository;
import org.cjstudio.holypoopsgrs_interface.game.model.HolyPoopsLeaderboard;
import org.cjstudio.holypoopsgrs_interface.game.model.HolyPoopsLeaderboardEntry;
import org.cjstudio.holypoopsgrs_interface.game.model.HolyPoopsPersonalRecord;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Path("holypoops")
@Component("holypoopsResource")
@Scope("singleton")
public class HolyPoopsResourcesImpl {

	@Resource
	private Repository<UserProfile> userProfileRepository;

	@GET
	@Path("leaderboard/{type}")
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	public HolyPoopsLeaderboard getLeaderboard(
			@PathParam(HolyPoopsLeaderboard.NAME_TYPE) String type, 
			@HeaderParam(HolyPoopsLeaderboard.NAME_LIMIT) Integer limit,
			@HeaderParam(HolyPoopsLeaderboard.NAME_KEY) String key) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/leaderboard/" + type);
		System.out.println("Type : " + type);
		System.out.println("Limit : " + limit);
		System.out.println("Key : " + key);

		/*
		//verify with key
		if(절대뚫리지않는굉장히복잡한알고리즘.굉장히복잡한키값인증(key) == false) {
			return null;
		}
		*/

		//retrieve top ten records
		List<UserProfile> profiles = userProfileRepository.retrieveWithRange(1, 10);
		ArrayList<HolyPoopsLeaderboardEntry> entries = new ArrayList<HolyPoopsLeaderboardEntry>();
		for(UserProfile profile : profiles) {
			entries.add(profile.toEntry());
		}

		HolyPoopsLeaderboard leaderboard = new HolyPoopsLeaderboard();
		leaderboard.entries = entries;
		leaderboard.leaderboardDate = new Date();

		if(type.equals(HolyPoopsLeaderboard.LEADERBOARD_TYPE_DAILY)) {
			leaderboard.type = HolyPoopsLeaderboard.LEADERBOARD_TYPE_DAILY;
		} else if(type.equals(HolyPoopsLeaderboard.LEADERBOARD_TYPE_WEEKLY)) {
			leaderboard.type = HolyPoopsLeaderboard.LEADERBOARD_TYPE_WEEKLY;
		} else if(type.equals(HolyPoopsLeaderboard.LEADERBOARD_TYPE_TOTAL)) {
			leaderboard.type = HolyPoopsLeaderboard.LEADERBOARD_TYPE_TOTAL;
		}

		System.out.println(leaderboard.toString());
		return leaderboard;
	}

	@GET
	@Path("record/{key}")
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	public HolyPoopsPersonalRecord getPersonalRecord(
			@PathParam(HolyPoopsPersonalRecord.NAME_KEY) String key) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/record/" + key);
		System.out.println("Key : " + key);

		/*
		//verify with key
		if(절대뚫리지않는굉장히복잡한알고리즘.굉장히복잡한키값인증(key) == false) {
			return null;
		}
		*/

		//retrieve record
		UserProfile profile = userProfileRepository.retrieve(key);
		System.out.println("Return : " + profile.toString());
		HolyPoopsPersonalRecord record = profile.toPersonalRecord();
		return record;
	}

	@POST
	@Path("record/{key}")
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	public HolyPoopsPersonalRecord setPersonalRecord(
			@PathParam(HolyPoopsPersonalRecord.NAME_KEY) String key, 
			@HeaderParam(HolyPoopsPersonalRecord.NAME_NAME) String name, 
			@HeaderParam(HolyPoopsPersonalRecord.NAME_SCORE) Integer score) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/record/" + key);
		System.out.println("Key : " + key);
		if(name != null)
			System.out.println("Name : " + name);
		if(score != null)
			System.out.println("Score : " + score);

		/*
		//verify with key
		if(절대뚫리지않는굉장히복잡한알고리즘.굉장히복잡한키값인증(key) == false) {
			return null;
		}
		(*/

		//retrieve record
		UserProfile profile = userProfileRepository.retrieve(key);

		boolean dirty = false;
		if(name != null) {
			//update name
			profile.name = name;
			dirty = true;
		}

		if(score != null) {
			if(score >= profile.highest) {
				profile.highest = score;
				profile.highestDate = new Date();
			}
			
			List<UserRecord> records = profile.topTenRecords;
			if(score >= records.get(records.size()-1).score) {
				// update score
				for(int i=0; i<records.size(); i++) {
					if(records.get(i).score > score) {
						continue;
					} else {
						UserRecord newRecord = new UserRecord();
						newRecord.score = score;
						newRecord.scoreDate = new Date();
						records.add(newRecord);
						records.remove(records.size()-1);
						break;
					}
				}
				dirty = true;
			}
		}

		if(dirty) userProfileRepository.update(profile);
		System.out.println("Return : " + profile.toString());
		HolyPoopsPersonalRecord record = profile.toPersonalRecord();
		return record;
	}

	@GET
	@Path("scoreboard")
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	public String getScoreboard(
			@HeaderParam(HolyPoopsLeaderboard.NAME_KEY) String key) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/scoreboard");
		System.out.println("Key : " + key);

		/*
		//verify with key
		if(절대뚫리지않는굉장히복잡한알고리즘.굉장히복잡한키값인증(key) == false) {
			return null;
		}
		*/

		//retrieve records
		List<UserProfile> profiles = userProfileRepository.retrieveAll();

		StringBuilder sb = new StringBuilder();
		for(int i=0; i<profiles.size(); i++) {
			sb.append("Profile " + i + "\n");
			sb.append(profiles.get(i).toString());
		}

		String result = sb.toString();
		System.out.println(result);
		return result;
	}
}
